#ValkyrieSky XML parser

import os, sys
from Sanae3D.lib.ModelObject import Model3D
from Sanae3D.lib.StructReader import StructReader

class ValkyrieSky_XML(Model3D):
    '''Replace 'ValkyrieSky_XML' with a suitable name of your choice. Try to follow
    the standard: GameName_FormatExt'''
    
    def __init__(self, obj3D=None, outFile=None, inFile=None):
        
        super(ValkyrieSky_XML,self).__init__("XML")
        self.obj3D = obj3D
        self.inFile = inFile
        self.outFile = outFile
        self.uv = []
        
    def read_name(self, n):
        '''Read null-terminated string, then add padding'''

        name = ""
        char = self.inFile.read_char()
        while char != "\x00":
            name = ''.join([name, char])
            char = self.inFile.read_char()
        self.inFile.seek(80 - (len(name) + 1), 1)
        return name
    
    def parse_unk(self, unk):
        '''section after faces'''
        
        for i in range(unk):
            self.inFile.read_float(5)
            self.inFile.seek(28, 1)
            
    def parse_faces(self, numFaces, meshName, matNum):
        
        for i in range(numFaces):
            
            self.inFile.read_long()
            v1, v2, v3 = self.inFile.read_long(3)
            
            self.create_face(meshName, i)
            self.add_face_verts(meshName, i, [v1, v2, v3])
            self.add_face_material(meshName, i, matNum)
            
    def parse_indices(self, numIndex, meshName):
        '''UV indices for each face'''
        
        for i in range(numIndex):
            id1, id2, id3 = self.inFile.read_long(3)
            
            u1, v1 = self.uv[id1]
            u2, v2 = self.uv[id2]
            u3, v3 = self.uv[id3]
            uv = [u1, v1, u2, v2, u3, v3]
            self.add_face_uv(meshName, i, uv)
            
            
    def parse_coords(self, numCoords, meshName):
        
        for i in range(numCoords):
            vx, vz, vy = self.inFile.read_float(3)
            
            self.create_vertex(meshName, i)
            self.add_coords(meshName, i, [vx, vy, vz])
            
    def parse_normals(self, numNorms, meshName):
        
        for i in range(numNorms):
            nx, ny, nz = self.inFile.read_float(3)
            
            self.add_vert_normals(meshName, i, [nx, ny, nz])
            
    def parse_UV(self, numUV, meshName):
        
        for i in range(numUV):
            tu, tv = self.inFile.read_float(2)
            self.uv.append([tu, tv])
                    
    def parse_file(self):
        '''Main parser method. Can be replaced'''
        
        header = self.read_name(80)
        unk1, unk2, unk3, unk4, sects1, unk6, unk7, unk8, unk9 = \
            self.inFile.read_long(9)
        
        for i in range(sects1):
            meshName = self.read_name(80)
        
        self.create_object(meshName)
        self.inFile.read_long()
        if sects1 == 3:
            self.inFile.read_long()
        self.inFile.read_float(9)
        self.inFile.read_long(5)
        
        self.inFile.seek(320, 1) #???
        self.inFile.read_float(9)
        self.inFile.read_long(5) 
        
        texName = self.read_name(80)
        self.create_material(0)
        self.add_material_name(0, "material")
        self.add_texture_name(0, texName)
        print texName
        self.inFile.seek(320, 1)
        
        self.inFile.seek(220, 1)
        prop = self.read_name(80)
        if prop == "Particle_View":                
            self.inFile.seek(220, 1)
            editable = self.read_name(80)
            print "editable", editable        
        
        meshType = self.inFile.read_long()
        
        if meshType in [1,2]:
            self.inFile.seek(184, 1)
            numCoords, numNorms, numUV, numIndex, numFaces, matNum, \
                     numUnk2, numUnk3= self.inFile.read_long(8)

            print numCoords, numNorms, numUV, numIndex, numFaces, matNum
            self.parse_coords(numCoords, meshName)
            self.parse_normals(numNorms, meshName)
            self.parse_UV(numUV, meshName)
            
            self.parse_faces(numFaces, meshName, matNum)
            self.parse_indices(numIndex, meshName)
        
def read_file(path):
    '''Read the file'''
    
    openFile = StructReader(open(path, 'rb'))
    obj = ValkyrieSky_XML(inFile=openFile)
    obj.parse_file()
    openFile.close()
    return obj

def write_file(path):
    
    pass

def definitions():
    '''Return the header, extension, and a description of the format'''
    
    return "OPTIMIZ", "XML", "Valkyrie Sky XML"

if __name__ == '__main__':
    
    file1 = "itembox2.xml"
    file2 = "wp_bow5.xml"
    file3 = "wp_staff0.xml"
    file4 = "dice01_a.xml"
    file5 = "wp_sword2.xml"
    file6 = "wp_staff21.xml"
    file7 = "mm_spear.xml"
    obj = read_file(file2)